package com.neusoft.bizcore.notice.notification.service.impl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.persistence.EntityNotFoundException;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.bizcore.notice.notification.converter.NoticeTemplateAttachmentConverter;
import com.neusoft.bizcore.notice.notification.converter.NoticeTemplateConverter;
import com.neusoft.bizcore.notice.notification.dto.NoticeTemplateAttachmentDTO;
import com.neusoft.bizcore.notice.notification.dto.NoticeTemplateDTO;
import com.neusoft.bizcore.notice.notification.model.NoticeTemplate;
import com.neusoft.bizcore.notice.notification.model.NoticeTemplateAttachment;
import com.neusoft.bizcore.notice.notification.repository.NoticeTemplateAttachmentRepository;
import com.neusoft.bizcore.notice.notification.service.NoticeTemplateAttachmentService;
import com.neusoft.bizcore.notice.notification.service.NoticeTemplateService;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class NoticeTemplateAttachmentServiceImpl implements NoticeTemplateAttachmentService {

    @Autowired
    private NoticeTemplateAttachmentRepository noticeTemplateAttachmentRepository;

    @Autowired
    private NoticeTemplateAttachmentConverter noticeTemplateAttachmentConverter;

    @Autowired
    private NoticeTemplateService noticeTemplateService;

    @Autowired
    private NoticeTemplateConverter noticeTemplateConverter;

    @Override
    public NoticeTemplateAttachmentDTO create(final MultipartFile file, final Long noticeTemplateId) {
        final NoticeTemplateDTO noticeTemplateDTO = this.noticeTemplateService.details(noticeTemplateId);
        final NoticeTemplate noticeTemplate = this.noticeTemplateConverter.toModel(noticeTemplateDTO);

        final List<NoticeTemplateAttachment> attachmentList =
                this.noticeTemplateAttachmentRepository.findByNoticeTemplate(noticeTemplate);

        NoticeTemplateAttachmentDTO dto;

        if (CollectionUtils.isNotEmpty(attachmentList)) {
            dto = this.noticeTemplateAttachmentConverter.toDTO(attachmentList.get(0));
        } else {
            dto = new NoticeTemplateAttachmentDTO();
        }

        try {
            final InputStream inputStream = file.getInputStream();
            final byte[] imageByte = new byte[(int) file.getSize()];
            inputStream.read(imageByte);
            if (noticeTemplate != null) {
                dto.setName(noticeTemplate.getName() + ".ftl");
            } else {
                dto.setName(file.getOriginalFilename());
            }
            dto.setTemplate(imageByte);
        } catch (final Exception e) {
            NoticeTemplateAttachmentServiceImpl.log.error("通知模板上传失败", e);
            throw new UnitedException("通知模板上传失败", new Object[] {});
        }

        final NoticeTemplateAttachment model = this.noticeTemplateAttachmentConverter.toModel(dto);

        model.setNoticeTemplate(noticeTemplate);

        this.noticeTemplateAttachmentRepository.save(model);
        return this.noticeTemplateAttachmentConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {
        final NoticeTemplateAttachment model;
        try {
            model = this.noticeTemplateAttachmentRepository.getOne(id);

        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        final long noticeTemplateId = model.getNoticeTemplate().getId();
        final NoticeTemplateDTO dto = this.noticeTemplateService.details(noticeTemplateId);
        final NoticeTemplate noticeTemplate = this.noticeTemplateConverter.toModel(dto);
        noticeTemplate.setTemplate(null);
        this.noticeTemplateService.update(noticeTemplateId, this.noticeTemplateConverter.toDTO(noticeTemplate));

        this.noticeTemplateAttachmentRepository.deleteById(id);
    }

    @Override
    public NoticeTemplateAttachmentDTO update(final Long id, final NoticeTemplateAttachmentDTO dto) {
        NoticeTemplateAttachment model;
        try {
            model = this.noticeTemplateAttachmentRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.noticeTemplateAttachmentConverter.toModel(dto);
        this.noticeTemplateAttachmentRepository.save(model);

        return this.noticeTemplateAttachmentConverter.toDTO(model);
    }

    @Override
    public NoticeTemplateAttachmentDTO details(final Long id) {
        final NoticeTemplateAttachment model;
        try {
            model = this.noticeTemplateAttachmentRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.noticeTemplateAttachmentConverter.toDTO(model);
    }

    @Override
    public void download(final Long id, final HttpServletResponse response) {
        try {
            final NoticeTemplateAttachmentDTO dto = this.details(id);

            final byte[] ftlFile = dto.getTemplate();
            response.setCharacterEncoding("UTF-8");
            final OutputStream outputSream = response.getOutputStream();
            final InputStream in = new ByteArrayInputStream(ftlFile);
            int len = 0;
            final byte[] buf = new byte[1024];
            while ((len = in.read(buf, 0, 1024)) != -1) {
                outputSream.write(buf, 0, len);
            }
            outputSream.close();
        } catch (final Exception e) {
            NoticeTemplateAttachmentServiceImpl.log.error("文件下载失败", e);
        }
    }

}
